التعامل مع المحارف وضبط إعدادات التوطين (Localization) في لغة C
تعد لغة C من أقدم لغات البرمجة وأكثرها استخدامًا في تطوير الأنظمة والبرمجيات التي تحتاج إلى أداء عالٍ وتحكم دقيق في الموارد. من أهم الجوانب التي يجب على المبرمجين الانتباه إليها في بيئات متعددة اللغات والثقافات هو التعامل مع المحارف وضبط إعدادات التوطين (Localization). هذا الجانب يمثل تحديًا كبيرًا نظرًا لاختلاف المعايير والقواعد بين اللغات والثقافات فيما يتعلق بالمحارف، الترميز، تنسيق الأرقام، التواريخ، والوقت، بالإضافة إلى الرسائل النصية المختلفة.
في هذا المقال سيتم تناول موضوع التوطين في لغة C بشكل مفصل، مع التركيز على كيفية التعامل مع المحارف المختلفة، كيفية استخدام مكتبة التوطين القياسية، وأهم الوظائف التي تقدمها هذه المكتبة لضبط وإدارة التوطين، كما سنتناول أهم التحديات والحلول المتاحة في هذا المجال.
مفهوم التوطين (Localization) وأهميته في البرمجة
التوطين هو عملية تكييف البرمجيات لتتلاءم مع لغة وثقافة معينة، بحيث يمكن استخدامها بسهولة من قبل المستخدمين في مناطق جغرافية مختلفة. يشمل التوطين:
-
تغيير اللغة المستخدمة في واجهة المستخدم.
-
تنسيق الأرقام والعملات حسب المعايير المحلية.
-
تنسيق التواريخ والأوقات بشكل يتناسب مع التقاليد المحلية.
-
التعامل مع المحارف والكتابات المختلفة (مثل الأبجدية العربية أو الصينية).
-
ضبط إعدادات الإدخال والإخراج للبيانات النصية.
في بيئة برمجة مثل لغة C، لا يتم التعامل مع هذه الأمور بشكل تلقائي، ولذلك تم توفير مكتبة التوطين القياسية لتسهيل هذه المهمة.
الترميزات النصية (Character Encodings)
قبل الخوض في تفاصيل التوطين في C، يجب فهم أن التعامل مع المحارف يعتمد أساسًا على الترميز النصي المستخدم لتمثيل الحروف والرموز. أشهر الترميزات:
-
ASCII: ترميز بسيط يدعم 128 محرفًا فقط، مناسب للغة الإنجليزية وبعض الرموز الخاصة.
-
Extended ASCII: يدعم 256 محرفًا، ويشمل بعض المحارف الخاصة بلغات أوروبية.
-
UTF-8: ترميز متغير الطول، يدعم جميع محارف Unicode، ويعتبر المعيار العالمي للتعامل مع النصوص متعددة اللغات.
-
UTF-16, UTF-32: ترميزات أخرى تدعم Unicode، لكنها أقل استخدامًا في لغة C بشكل مباشر.
التحدي الأكبر في لغة C هو أن المكتبة القياسية (Standard Library) تاريخيًا تعتمد على ترميز ASCII أو الترميزات المحلية التي تختلف من نظام إلى آخر، مما يجعل التعامل مع النصوص المعقدة والمتعددة اللغات أكثر تعقيدًا.
مكتبة التوطين القياسية في C
لتسهيل التعامل مع إعدادات التوطين، توفر لغة C مكتبة مخصصة تسمى locale.h، والتي توفر مجموعة من الوظائف والأنواع المرتبطة بضبط واستخدام التوطين.
مفهوم locale_t
في C، الـ locale هو مجموعة من الإعدادات التي تحدد قواعد التعامل مع اللغة والثقافة، وتشمل:
-
ترميز المحارف.
-
قواعد ترتيب المحارف (Collation).
-
تنسيقات الأرقام، العملات، التواريخ، والأوقات.
-
نصوص الرسائل وأسلوب العرض.
الوظائف الرئيسية في مكتبة locale.h
1. setlocale
c#include
char *setlocale(int category, const char *locale);
وظيفة setlocale تستخدم لضبط أو استعلام الإعدادات الخاصة بالتوطين لفئة معينة.
-
categoryهي فئة التوطين التي نريد تعديلها، ويمكن أن تكون إحدى القيم التالية:-
LC_ALL: كل الإعدادات. -
LC_COLLATE: قواعد ترتيب المحارف. -
LC_CTYPE: خصائص المحارف مثل الأحرف الكبيرة والصغيرة. -
LC_MONETARY: تنسيق العملات. -
LC_NUMERIC: تنسيق الأرقام. -
LC_TIME: تنسيق التواريخ والأوقات.
-
-
localeهو اسم إعداد التوطين المراد تفعيله مثل"en_US.UTF-8"أو"ar_SA.UTF-8".
مثال على استخدام setlocale:
c#include
#include
int main() {
setlocale(LC_ALL, "ar_SA.UTF-8"); // تعيين التوطين إلى العربية السعودية مع UTF-8
printf("مرحبًا بالعالم!\n");
return 0;
}
إذا تم تمرير NULL بدلاً من اسم التوطين، فإن الوظيفة تقوم بإرجاع اسم الإعداد الحالي.
2. localeconv
c#include
struct lconv *localeconv(void);
وظيفة localeconv تقوم بإرجاع مؤشر إلى هيكل بيانات من نوع lconv يحتوي على معلومات تفصيلية حول تنسيقات الأرقام والعملات المستخدمة في التوطين الحالي.
هيكل lconv يحتوي على حقول عديدة مثل:
| الحقل | الوصف |
|---|---|
decimal_point |
رمز الفاصل العشري (مثل . أو ,) |
thousands_sep |
رمز فاصل الآلاف |
grouping |
كيفية تجميع الأرقام |
int_curr_symbol |
رمز العملة الدولي (مثل USD) |
currency_symbol |
رمز العملة المحلي |
mon_decimal_point |
فاصل عشري للعملة |
mon_thousands_sep |
فاصل الآلاف للعملة |
positive_sign |
رمز الإشارة الإيجابية |
negative_sign |
رمز الإشارة السلبية |
int_frac_digits |
عدد المنازل العشرية للعملة الدولية |
frac_digits |
عدد المنازل العشرية للعملة المحلية |
يمكن استخدام هذه المعلومات لتنسيق الأرقام والعملات بطريقة تتوافق مع الإعداد المحلي.
3. التعامل مع خصائص المحارف (LC_CTYPE)
تحتوي مكتبة C أيضًا على وظائف خاصة بفئة LC_CTYPE التي تتحكم في كيفية تصنيف المحارف، والتعرف على أحرف معينة مثل الحروف الكبيرة، الصغيرة، الأرقام، أو المحارف البيضاء.
بعض الوظائف المهمة في هذا المجال:
-
isalpha(int c): تتحقق إذا كان المحرف حرفًا أبجديًا. -
isdigit(int c): تتحقق إذا كان المحرف رقمًا. -
islower(int c): تتحقق إذا كان المحرف حرفًا صغيرًا. -
isupper(int c): تتحقق إذا كان المحرف حرفًا كبيرًا. -
tolower(int c): تحويل المحرف إلى حرف صغير. -
toupper(int c): تحويل المحرف إلى حرف كبير.
هذه الوظائف تتأثر بإعدادات التوطين الحالية، فمثلاً عند تعيين التوطين إلى "ar_SA.UTF-8" فإن isalpha ستتعامل مع الحروف العربية بشكل صحيح.
التعامل مع النصوص متعددة البايتات (Multibyte) والمحارف الواسعة (Wide Characters)
لغة C التقليدية تعتمد على تمثيل المحارف كنوع char وهو عادة بايت واحد. ولكن لدعم اللغات التي تستخدم محارف أكبر من 1 بايت (مثل العربية، الصينية، اليابانية)، توفر اللغة نوعين مهمين:
-
محارف واسعة (Wide Characters):
wchar_t -
نصوص متعددة البايت (Multibyte Strings)
محارف واسعة (Wide Characters)
wchar_t هو نوع بيانات مخصص لتمثيل محارف قد تكون أكبر من 1 بايت. يستخدم بشكل رئيسي مع وظائف من مكتبة . هذا النوع يسمح بتمثيل المحارف Unicode بشكل أكثر سهولة.
مثال على تعريف سلسلة محارف واسعة:
c#include
#include
#include
int main() {
setlocale(LC_ALL, "en_US.UTF-8");
wchar_t ws[] = L"مرحبا بالعالم";
wprintf(L"%ls\n", ws);
return 0;
}
نصوص متعددة البايت (Multibyte Strings)
هي سلاسل نصية قد تحتوي على محارف تتكون من أكثر من بايت واحد. توفر مكتبة و وظائف للتحويل بين النصوص متعددة البايتات ونصوص المحارف الواسعة، مثل:
-
mbstowcs: تحويل نص متعدد البايت إلى نص محارف واسعة. -
wcstombs: تحويل نص محارف واسعة إلى نص متعدد البايت.
وظائف التعامل مع النصوص متعددة البايت والمحارف الواسعة
1. mbstowcs
csize_t mbstowcs(wchar_t *dest, const char *src, size_t max);
تقوم هذه الوظيفة بتحويل نص متعدد البايت (src) إلى نص محارف واسعة (dest) حتى حد أقصى من المحارف (max).
2. wcstombs
csize_t wcstombs(char *dest, const wchar_t *src, size_t max);
تقوم بتحويل نص محارف واسعة إلى نص متعدد البايت.
3. mbtowc و wctomb
-
mbtowc(wchar_t *pwc, const char *s, size_t n)تحول محرف متعدد البايت إلى محرف واسع. -
wctomb(char *s, wchar_t wc)تحول محرف واسع إلى محرف متعدد البايت.
ضبط التوطين في بيئات متعددة المنصات
التحكم في التوطين لا يقتصر فقط على اللغة التي تستخدمها، بل يعتمد أيضًا على دعم نظام التشغيل. في أنظمة UNIX/Linux، يمكن التبديل بسهولة بين إعدادات التوطين باستخدام أسماء مثل "en_US.UTF-8"، "ar_SA.UTF-8", أو "fr_FR.UTF-8".
في نظام ويندوز، قد تكون أسماء التوطين مختلفة ويجب استخدام معايير ويندوز الخاصة. كذلك، دعم UTF-8 قد لا يكون مفعلًا افتراضيًا، ولذلك من الضروري التأكد من ضبط إعدادات النظام.
تنسيق الأرقام والتواريخ والعملة حسب التوطين
بعد تعيين إعدادات التوطين المناسبة، يمكن استخدام مكتبة printf مع التنسيقات المختلفة للحصول على المخرجات المناسبة.
لكن في لغة C القياسية لا توجد دوال مدمجة متقدمة للتعامل مع تنسيقات التواريخ أو العملات حسب التوطين. لذلك، غالبًا ما يتم استخدام مكتبات خارجية مثل ICU (International Components for Unicode) أو POSIX extensions لتوفير وظائف أكثر شمولًا.
مثال عملي لطباعة رقم عشري مع فصل الآلاف وفقًا للتوطين
c#include
#include
int main() {
setlocale(LC_ALL, "en_US.UTF-8");
struct lconv *lc = localeconv();
double number = 1234567.89;
printf("Decimal point: %s\n", lc->decimal_point);
printf("Thousands separator: %s\n", lc->thousands_sep);
printf("Formatted number: %'f\n", number);
return 0;
}
في بعض البيئات، %‘f يستخدم لتفعيل تنسيق الأعداد مع فواصل الآلاف، لكن هذا يعتمد على دعم الـ printf في النظام.
التحديات الشائعة في التعامل مع التوطين في لغة C
-
دعم محدود للنصوص متعددة البايتات: معظم وظائف C الأصلية تعالج النصوص كـ
charفقط، مما يصعب التعامل مع لغات مثل العربية والصينية. -
عدم وجود دعم متكامل لتنسيق التواريخ والأوقات حسب التوطين: تحتاج إلى مكتبات خارجية.
-
اعتماد أسماء التوطين على النظام: أسماء التوطين تختلف بين أنظمة التشغيل، مما يجعل البرمجة متعددة المنصات أكثر تعقيدًا.
-
تعقيد استخدام المحارف الواسعة: الاستخدام غير المباشر لنوع
wchar_tوالتعامل مع التحويلات بين النصوص متعددة البايت ونصوص المحارف الواسعة يزيد من تعقيد الكود.
خاتمة
التعامل مع المحارف وضبط إعدادات التوطين في لغة C يمثل جزءًا أساسيًا من تطوير البرمجيات التي تستهدف جمهورًا عالميًا. معرفة كيفية استخدام مكتبة locale.h والوظائف المرتبطة بها، إلى جانب فهم الترميزات النصية وكيفية التعامل مع النصوص متعددة البايت والمحارف الواسعة، هي مهارات ضرورية لضمان توافق البرمجيات مع مختلف اللغات والثقافات.
بالرغم من التحديات التي تواجه المطورين في هذا المجال باستخدام لغة C، إلا أن التزامن مع مكتبات خارجية متخصصة واستخدام الترميزات الحديثة مثل UTF-8 يوفر فرصًا واسعة لجعل البرامج متعددة اللغات أكثر مرونة واحترافية.
المراجع
-
كتاب “The C Programming Language” لـ Kernighan و Ritchie (الطبعة الثانية).
-
وثائق مكتبة C القياسية (locale.h, wchar.h) – ISO/IEC 9899:1999.

